package com.dk.config.handler;

import com.dk.common.exception.JdbcConnectException;
import com.dk.common.utils.Constant;
import com.dk.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;

/**
 * 全局异常处理
 */
@Slf4j
@RestControllerAdvice
//@ControllerAdvice("com.dk.api.controller")指定包进行异常处理
public class GlobalExceptionHandler {

    @ExceptionHandler({ConstraintViolationException.class, MethodArgumentNotValidException.class , JdbcConnectException.class})
    public R violationException(Exception exception) {
        if (exception instanceof ConstraintViolationException) { //使用关键字instanceof 判断 ConstraintViolationException 是否为 Exception 直接或间接子类
            return constraintViolationException((ConstraintViolationException) exception); //调用下面方法，返回结果
        }else if(exception instanceof MethodArgumentNotValidException){
            return new R().error(Constant.statusCode.REQ_ERROR.getCode(), ((MethodArgumentNotValidException) exception).getBindingResult().getFieldError().getDefaultMessage());
        }else if(exception instanceof  JdbcConnectException){
            return new R().error(Constant.statusCode.REQ_ERROR.getCode(),((JdbcConnectException) exception).getMsg());
        }
        return new R().error(Constant.statusCode.RES_ERROR.getCode(), "server error"); // 否则跑出 server error
    }
    // 当我们没有此方法，空参访问localhost:8080/login 会抛出ConstraintViolationException 异常
    public R constraintViolationException(ConstraintViolationException ex) {
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        if (!CollectionUtils.isEmpty(constraintViolations)) { //判断是否为空
            StringBuilder sb = new StringBuilder();
            for (ConstraintViolation constraintViolation : constraintViolations) { //遍历 ConstraintViolation
                sb.append(constraintViolation.getMessage()).append(","); // 吧错误信息循环放到sb中, 并以逗号隔开
            }
            String errorMessage = sb.toString(); // 获得异常信息字符串
            return new R().error(400,errorMessage);
        }
        return new R().error(500,"server error"); // 否则跑出 server error
    }
}
